package com.base.web.core.aspect;

import com.base.web.core.util.TimeUtil;
import com.base.web.dao.master.auth.LogMapper;
import com.base.web.model.master.auth.Log;
import com.base.web.model.master.auth.User;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Date;

/**
 * Created with IntelliJ IDEA.
 * Description: http请求处理切面
 *
 * @Author: rentie
 * @Date: 2018/7/16 11:12
 */
@Aspect
@Component
public class LogAspect {

    private Long requestTime;

    private Log log = new Log();

    //日志打印方法
    private Logger logger = LoggerFactory.getLogger(LogAspect.class);

    @Resource
    private LogMapper logMapper;

    /**
     * 切入点，表达式写法自行百度
     */
    @Pointcut("execution(public * com.base.web.*.controller..*.*(..))")
    public void logPointCut() {

    }

    /**
     * controller方法执行之前执行，请求参数记录
     */
    @Before("logPointCut()")
    public void doBefore(JoinPoint joinPoint) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        //用户信息
        User user = (User) request.getSession().getAttribute("user");
        if (user != null) {
            log.setUser(user.getLoginName());
        } else {
            log.setUser("null");
        }

        //初始化请求时间
        requestTime = TimeUtil.getCurrentTimeMillisecond();

        log.setRequestTime(new Date());

        //url
        logger.info("url={}", request.getRequestURL());
        log.setUrl(request.getRequestURL().toString());

        //method(POST/GET ....)
        logger.info("method={}", request.getMethod());
        log.setMethod(request.getMethod());

        //ip
        logger.info("ip={}", request.getRemoteAddr());
        log.setIp(request.getRemoteAddr());

        String classMethod = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
        //类方法
        logger.info("class_method={}", classMethod);
        log.setClassMethod(classMethod);


        //参数
        logger.info("args={}", joinPoint.getArgs());
        log.setArgs(Arrays.toString(joinPoint.getArgs()));

    }

    /**
     * controller方法返回之后执行
     */
    @AfterReturning(pointcut = "logPointCut()", returning = "object")
    public void doAfterReturning(Object object) {
        //获得请求返回时间
        Long responseTime = TimeUtil.getCurrentTimeMillisecond();

        if (object != null) {
            //返回值打印
            logger.info("response={}", object.toString());
        } else {
            //返回值打印
            logger.info("response=null");

        }

        log.setResponse("200");
        //请求耗时
        logger.info("Request time(millisecond)={}", responseTime - requestTime);
        log.setSpendTime(new Long(responseTime - requestTime).intValue());

        logMapper.insertSelective(log);
    }

    /**
     * 拦截异常，记录异常日志，并设置对应的异常信息
     * 目前只拦截Exception
     *
     * @param e 异常对象
     */
    @AfterThrowing(pointcut = "logPointCut()", throwing = "e")
    public void handle(JoinPoint point, Exception e) {
        log.setResponse("500");
        log.setException("异常信息：" + e.getMessage());
        logMapper.insertSelective(log);
    }

}